﻿#nullable enable
namespace Application.Service.Permissions;

/// <summary>
/// 权限管理服务
/// <para>功能：提供权限管理的Web API接口，支持权限信息的增删改查操作</para>
/// <list type="bullet">
/// <item><description>权限信息查询：获取所有权限、单个权限详情</description></item>
/// <item><description>权限管理：创建、更新、删除权限信息</description></item>
/// <item><description>权限编码管理：确保权限编码的唯一性</description></item>
/// <item><description>权限数据封装：为权限分配提供标准化的数据格式</description></item>
/// </list>
/// </summary>
[ApiDescriptionSettings(SplitCamelCase = false)]
public sealed class PermissionService : IDynamicApiController, ITransient, IPermissionService
{
    private readonly ISqlSugarClient _db;

    public PermissionService(ISqlSugarClient db)
    {
        _db = db;
    }

    /// <summary>
    /// 查询系统中所有定义的权限信息
    /// </summary>
    /// <returns>返回包含所有权限信息的集合</returns>
    public async Task<IEnumerable<Permission>> GetAllAsync()
    {
        var dbCopy = _db.CopyNew();
        try
        {
            return await dbCopy.Queryable<Permission>().OrderBy(p => p.Id).ToListAsync();
        }
        catch (Exception ex)
        {
            Log.Error($"获取权限列表失败!", ex);
            throw Oops.Bah($"获取权限列表失败!", ex);
        }
        finally
        {
            dbCopy.Close();
            dbCopy.Dispose();
        }
    }

    /// <summary>
    /// 通过权限ID精确查询特定权限的详细信息
    /// </summary>
    /// <param name="permissionId">权限Id</param>
    /// <returns>返回指定权限的完整信息或null（权限不存在）</returns>
    public async Task<Permission?> GetAsync(int permissionId)
    {
        var dbCopy = _db.CopyNew();
        try
        {
            return await dbCopy.Queryable<Permission>().InSingleAsync(permissionId);
        }
        catch (Exception ex)
        {
            Log.Error($"获取权限失败!", ex);
            throw Oops.Bah($"获取权限失败!", ex);
        }
        finally
        {
            dbCopy.Close();
            dbCopy.Dispose();
        }
    }

    /// <summary>
    /// 在系统中定义新的权限项
    /// </summary>
    /// <param name="dto">权限实体</param>
    /// <returns>返回创建权限、错误信息和创建的权限信息结果元组</returns>
    public async Task<(bool ok, string? error, Permission? value)> CreateAsync(Permission dto)
    {
        var dbCopy = _db.CopyNew();
        try
        {
            if (await dbCopy.Queryable<Permission>().AnyAsync(p => p.Code == dto.Code))
                return (false, $"权限编码已存在: {dto.Code}", null);

            var id = await dbCopy.Insertable(dto).ExecuteReturnIdentityAsync();
            dto.Id = id;
            return (true, null, dto);
        }
        catch (Exception ex)
        {
            Log.Error($"创建权限失败!", ex);
            throw Oops.Bah($"创建权限失败!", ex);
        }
        finally
        {
            dbCopy.Close();
            dbCopy.Dispose();
        }
    }

    /// <summary>
    /// 修改指定权限的基本信息和属性
    /// </summary>
    /// <param name="permissionId">权限Id</param>
    /// <param name="dto">权限实体</param>
    /// <returns>返回权限更新、错误信息和更新后的权限信息结果元组</returns>
    public async Task<(bool ok, string? error, Permission? value)> UpdateAsync(int permissionId, Permission dto)
    {
        var dbCopy = _db.CopyNew();
        try
        {
            var exists = await dbCopy.Queryable<Permission>().InSingleAsync(permissionId);
            if (exists is null) return (false, "权限不存在", null);

            if (!string.Equals(exists.Code, dto.Code, StringComparison.Ordinal) &&
                await dbCopy.Queryable<Permission>().AnyAsync(p => p.Code == dto.Code))
            {
                return (false, $"权限编码已存在: {dto.Code}", null);
            }

            exists.Code = dto.Code;
            exists.Name = dto.Name;
            exists.Description = dto.Description;
            exists.OwnerUserId = dto.OwnerUserId;

            await dbCopy.Updateable(exists).ExecuteCommandAsync();
            return (true, null, exists);
        }
        catch (Exception ex)
        {
            Log.Error($"更新权限失败!", ex);
            throw Oops.Bah($"更新权限失败!", ex);
        }
        finally
        {
            dbCopy.Close();
            dbCopy.Dispose();
        }
    }

    /// <summary>
    /// 从系统中永久删除指定权限及其相关数据
    /// </summary>
    /// <param name="permissionId">权限Id</param>
    /// <returns>预期结果：返回删除权限和错误信息结果元组</returns>
    public async Task<(bool ok, string? error)> DeleteAsync(int permissionId)
    {
        var dbCopy = _db.CopyNew();
        try
        {
            var exists = await dbCopy.Queryable<Permission>().InSingleAsync(permissionId);
            if (exists is null) return (false, "权限不存在");

            var tran = await dbCopy.Ado.UseTranAsync(async () =>
            {
                await dbCopy.Deleteable<UserPermission>().Where(up => up.PermissionId == permissionId).ExecuteCommandAsync();
                await dbCopy.Deleteable<Permission>().In(permissionId).ExecuteCommandAsync();
            });

            return tran.IsSuccess ? (true, null) : (false, tran.ErrorMessage);
        }
        catch (Exception ex)
        {
            Log.Error($"删除权限失败!", ex);
            throw Oops.Bah($"删除权限失败!", ex);
        }
        finally
        {
            dbCopy.Close();
            dbCopy.Dispose();
        }
    }
}

